#include "mainwindow.h"
#include "ui_mainwindow.h"

#include"secinfo.h"
#include"message.h"
#include<QNetworkRequest>

using namespace std;

//#define DEBUG_VERSION
const auto SPACE = " ";

const auto NOW_DETAIL = 10001;  // 获取最新的消息
const auto SETTING_CLOSE_BUZZER = 10002; // 关闭蜂鸣器
const auto SETTING_OPEN_BUZZER = 10003 ;   //打开蜂鸣器
const auto SETTING_ILL_BUZZER = 10004;   // 疑似非法进入的蜂鸣器关闭

const auto TEST_MESSAGE_STR = "{\"code\":233,\"message\":\"hello_test_message\",\"mac\":\"00124B001795E329\"}";

const QString  WS_URL = "ws://www.neecola.com:8888/user/pr/ws?phone=13123456789&proxyId=233";
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),serial(nullptr)
{
    ui->setupUi(this);


    //查找可用的串口
    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {

            ui->PortBox->addItem(serial.portName());
            serial.close();
        }
    }
    //设置波特率下拉菜单默认显示第0项
    ui->BaudBox->setCurrentIndex(0);

    ws = new QWebSocket();

    connect(ws,SIGNAL(textMessageReceived(const QString &)),this,SLOT(onWsRecievedMessage(const QString &)));
    connect(ws,&QWebSocket::connected,[this](){

        qDebug()<<"connected";
        SecInfo info ;
        ws->sendTextMessage(info.toJSON());

    });


    // 当见检测到 新信号. mac 字段发生变化的时候
    connect(this,&MainWindow::macHadChaned,[this](const QString & addr){
        if (this->ws == nullptr ){
            return ;
        }

        // ws 没有连接
        if (this->ws->state() == QAbstractSocket::UnconnectedState){
            this->request.setRawHeader("mac",addr.toUtf8());
            this->ws->open(this->request);
        }

    });

    // ws 断开连接
    connect(this->ws, &QWebSocket::disconnected,[this](){
        qDebug()<<"ws disconnected "<<"this. request";

        // 重新连接
        this->ws->open(this->request);
    });


    // 测试版本......
#ifdef DEBUG_VERSION

    ui->pushButton->setVisible(true);
    ui->lineEdit->setVisible(true);

    SecInfo secinfo;
    secinfo.setGas(23);
    secinfo.setHum(77);
    secinfo.setTem(23);
    secinfo.setIllegal(0);
    secinfo.setMac("00124B001795E329");
    auto text = secinfo.toJSON();

    SecInfo  d  = secinfo.parseSecInfo(text);
    auto dR = SecInfo(std::move( d));
    qDebug()<<" == "<<dR.toJSON();

    auto dtext = d.toJSON();


    qDebug()<<" dtext = "<<dtext;

    Message msg;
    msg.setCode(10001);
    msg.setMac("00124B001795E329");
    qDebug()<<"msg "<< msg.toJSON();
    msg = msg.parserFromJSON(msg.toJSON());
    qDebug()<<"xx "<< msg.toJSON();

    Message m_test = Message::parserFromJSON(TEST_MESSAGE_STR);
    qDebug()<<" test "<<m_test.toJSON();




#endif

    // 设置不显示多余的窗口控件
    ui->btn_connect->setVisible(0);
    ui->lineEdit->setVisible(false);
    ui->textEdit->setVisible(false);
    ui->pushButton->setVisible(false);
    ui->pushButton__write->setVisible(false);
    ui->textEdit_2->setVisible(false);
    ui->SendButton->setVisible(false);

    // 固定窗口大小
    setFixedSize(200,320);
    //
    request.setRawHeader("whoareu","proxy");
    // 设置硬件的地址作为请求的头部信息
    request.setRawHeader("mac","00124B001795E329");
    qDebug()<<"_WS_URL "<<WS_URL;

#ifdef DEBUG_VERSION
    request.setUrl(QUrl("ws://localhost:8888/user/pr/ws?phone=13123456789&proxyId=233"));
#else
    request.setUrl(WS_URL);
#endif
    ws->open(request);


    //
    connect(this,SIGNAL(onQueuePush(QString)),this,SLOT(slOnQueuePush(QString)));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_OpenSerialButton_clicked()
{
    if(ui->OpenSerialButton->text() == tr("打开串口"))
    {
        serial = new QSerialPort;
        //设置串口名
        serial->setPortName(ui->PortBox->currentText());
        //打开串口
        serial->open(QIODevice::ReadWrite);
        //设置波特率
        serial->setBaudRate(QSerialPort::Baud115200);//设置波特率为115200
        //设置数据位数
        switch (ui->BitBox->currentIndex())
        {
        case 8:
            serial->setDataBits(QSerialPort::Data8);//设置数据位8
            break;
        default:
            break;
        }
        //设置校验位
        switch (ui->ParityBox->currentIndex())
        {
        case 0:
            serial->setParity(QSerialPort::NoParity);
            break;
        default:
            break;
        }
        //设置停止位
        switch (ui->BitBox->currentIndex())
        {
        case 1:
            serial->setStopBits(QSerialPort::OneStop);//停止位设置为1
            break;
        case 2:
            serial->setStopBits(QSerialPort::TwoStop);
        default:
            break;
        }
        //设置流控制
        serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制

        //关闭设置菜单使能
        ui->PortBox->setEnabled(false);
        ui->BaudBox->setEnabled(false);
        ui->BitBox->setEnabled(false);
        ui->ParityBox->setEnabled(false);
        ui->StopBox->setEnabled(false);
        ui->OpenSerialButton->setText(tr("关闭串口"));

        //连接信号槽
        QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData);

        serial->write("10004");


    }
    else
    {
        //关闭串口
        serial->clear();
        serial->close();
        serial->deleteLater();

        //恢复设置使能
        ui->PortBox->setEnabled(true);
        ui->BaudBox->setEnabled(true);
        ui->BitBox->setEnabled(true);
        ui->ParityBox->setEnabled(true);
        ui->StopBox->setEnabled(true);
        ui->OpenSerialButton->setText(tr("打开串口"));


    }




}
//读取接收到的信息
void MainWindow::ReadData()
{
    static QString s_str;
    const QString STAR ="T&H&G&I&D";
    QByteArray buf;
    buf = serial->readAll();

    if(!buf.isEmpty())
    {
        QString s =  QString(buf );
        if (s.startsWith(STAR)){
            s.remove('\n');
            s_str .append(s);
            return ;
        } else {
            s_str .append(s);
            s = s_str;
            s_str.clear();
        }

        qDebug()<<"s = "<<s;


        // 如果没有连接,建立连接
        if ( !ws->isValid()){

        }

        if (s .length()  < 34 ){
            s.clear();
            return ;
        }


        auto ssplit = s.split(":");
        QString ss = ssplit[1];
        auto sqs = ss.split(SPACE);

        QString str = ui->textEdit->toPlainText();
        str+=s +"\n";
        ui->textEdit->clear();
        ui->textEdit->setText(str);

        auto stem = sqs.at(0);
        auto shum = sqs.at(1);
        auto sillegal = sqs.at(3);
        auto sgas = sqs.at(2);

        auto sSubNum = sqs.at(4);   //发送异常的子结点的编号
        auto sMacAddr = sqs.at(5);  // 地址编号

        // 如果当前对象的mac 地址为空, 为则为mac 地址赋值
        if (mac == ""){
            // 设置mac 地址 .
            // 发送 mac 变化的信息
            prSetMac(sMacAddr);
        }
        int tem = stem.toInt();
        int hum = shum.toInt();
        bool illegal = sillegal.toInt();
        bool gas = sgas.toInt();

        SecInfo info;

        info.setGas(gas);
        info.setHum(hum);
        info.setIllegal(illegal);
        info.setTem(tem);

        // 设置子结点和mac 地址
        info.setSubNum(sSubNum.toInt());
        info.setMac(sMacAddr);

        //  qDebug()<<"data"<<QString(buf) <<", length "<<QString(buf).length()<<" , sub"<<ss <<" , sqs "<<sqs <<", stem "<<stem <<" , info "<<info.getGas()<<",tem "<<info.getTem()<<", hum "<<info.getHum()<<" , illegal "<<info.getIllegal();

#ifdef DEBUG_VERSION
        qDebug()<<" , info "<<info.getGas()<<",tem "<<info.getTem()<<", hum "<<info.getHum()<<" , illegal "<<info.getIllegal() <<" toString "<<info.toJSON();

#endif

        ws->sendTextMessage(info.toJSON());
        buf.clear();

    }

}

//发送按钮槽函数
// ....
void MainWindow::on_SendButton_clicked()
{
    serial->write(ui->textEdit_2->toPlainText().toLatin1());
}

void MainWindow::on_pushButton_clicked()
{
    static SecInfo info ;
    // info.setGas(1);
    info.setHum(65);
    info.setSubNum(0);
    info.setIllegal(1);
    info.setTem(27);
    info.setMac("00124B001795E329");
    this->ws->sendTextMessage(info.toJSON());
    qDebug()<<"测试 "<<info.toJSON();
    if (this->ws->state() == QAbstractSocket::ListeningState){

    }
}

void MainWindow::on_btn_connect_clicked()
{
    auto uid=  ui->lineEdit->text().trimmed();
}

void MainWindow::prSetMac(const QString addr)
{
    this->mac = addr;
    emit macHadChaned(addr);
}


// 收到消息的响应函数
void MainWindow::onWsRecievedMessage(const QString &text)
{
    qDebug()<<"get message "<<text;

    // 如果接收的消息不是 { 开头的.. 直接退出
    if (!text.startsWith("{")){
        return ;
    } else {

        qDebug()<<" start with {" << text ;
    }
    Message msg = Message::parserFromJSON(text);

    //     if (msg.getMac() == ""){
    //         queue_sub_mac.push_back("00124B001795E329");

    //         emit onQueuePush("00124B001795E329");

    //         return ;
    //     }


    // if serial is nullptr return
    // todo maybe do more
    if (serial == nullptr ){
        qDebug()<<" serial is nullptr";
        return;
    }

    //  if the serial port is not open return
    if ( !serial->isOpen() ){
        qDebug()<<"get message but port not open     ";
        return ;
    } else {
        qDebug()<<"open";
    }


    auto code =  msg.getCode();
    auto wlen = 0 ;
    // 如果 code != 0
    // 请求控制
    if (code != 0 ) {
        // 10002 关闭蜂鸣器
        // 10003 打开蜂鸣器
        if (code == 10002){

            wlen = this->serial->write("10002");
        } else if (code == 10003) {
            wlen = this->serial->write("10003");

        }



    } else {
        // 获取最新的数据
        wlen = this->serial->write(msg.getMac().toLatin1());
        qDebug()<<"write "<<msg.getMac();

    }


    qDebug()<<"get message"<<msg.toJSON()<<" text"<<text <<" wlen"<<wlen;

}

// 当请求的结点加入到 请到请求队列
void MainWindow::slOnQueuePush(const QString &mac)
{
    qDebug()<<"request "<< mac << ", len "<<queue_sub_mac.length();
}

// 当 队列弹出 请求结点的数据

void MainWindow::slOnQueuePop(const QString &mac)
{

}

// 测试向串口写入数据
// 返回写入的字节数
// 如果serial 为空, 直接返回
void MainWindow::on_pushButton__write_clicked()
{
    if(serial == nullptr){
        qDebug()<<" nullptr";
        return ;
    }

    auto len =     serial->write("10004");

    qDebug()<<"write "<< len;

}
